HappyDB :)

Why are you happy?

What makes your happy moments different from others?

By Xinyi Hu
BoJack Horseman



HappyDB is a large scale collection of happy moments on Amazon Mechanical Turk (MTurk) workers. And HappyDB also collected the demographic information of these workers.

Happiness is the emotion that we all share. However, things that make us happy might be relatively different from each other. Therefore, this project aims to analyze what makes people happy, and whether gender, marital status, parenthood and cultural background would differ the things and events that make people feel happy.

Section 1: Overview of The Happy Moments

This section focuses on analyzing all happy moments regardless of workers’ demographic information.

Part 1: Wordcloud

Words that frequently appeared in MTurk workers’ happy moments descriptions are: friend, day, time, watched, family and home etc. Thus, generally people will feel happy about things or events related to their friends, families, watching shows and so on.

Part 2: Relationships Between Words

In this part, I am interested in the relationships between words in all the happy moments descriptions. I want to whether examine which words tend to follow others immediately, or that tend to co-occur within the same documents.

I visualize some details of the text structure. We can see that words like visit, party and school are often followed by the word friend, which means when these events are related to friends, people usually get happy.

We also see some pairs or triplets along the outside that form common short phrases related to happy moments, such as brought home and read book.

Part 3: Topic Modeling

Now in this part, I apply topic modeling to all happy moments corpus. I set the number of topics to be 9, which is the same as the number of ‘topic_dict’ in HappyDB data folder.

According to the above plots and the words relationships we just found out, I sort the topics as follows:

\[ Topic\ 1: Shopping \\ Topic\ 2: Entertainment \\ Topic\ 3: People \\ Topic\ 4: Pets \\ Topic\ 5: Work \\ Topic\ 6: Exercise\\ Topic\ 7: Food \\ Topic\ 8: School \\ Topic\ 9: Family \]

Section 2: Analyze Happy Moments in Different Clusters

In this section, I group HappyDB data into similar categories according to Amazon MTurk workers’ demographic data including gender, parenthood, marital status and continent.

Part 1: Gender

Male

Female

The wordclouds look good, but except for words day, time and friend, we can hardly see other words clearly. So let’s check these popular words by other visualization plot.

In both plots, the first 3 words are day, time and friend. And Their frequencies are almost equivalent in female data set, while in male data set, the word frequency of friend is much higher than the other two words. The fourth word in both data set is spouse, which is good.

In the male data set, words played and watched rank higher than family. But in female data set, words related to family and home are in the front. So you can see the differences of happy moments between female and male.

Part 2: Parenthood

The popular words in these two clusters are apparently different. For those who have kids, although day, time and friends are still the frequent words in their happy moments descriptions, family related words like daughter and son contribute to their happy moments a lot.

While in the no-child cluster, except for words day, time and friends, we can see words related to entertainment show up frequently, such as game, played and watched. And this result is quite reasonable.

Part 3: Marital Status

In each marital status, words day, time and friends are still frequently appear. And in cluster single, words related to entertainment are popular. In cluster married, family related words rank higher than the words watched, which suggests that positive things or events related to family usually make married people happy and these happy moments tend to be remembered.

In clusters divorced and separated, words daughter, son and watched rank high, while words home ranks lower. To my mind, this makes sense since divorce is a formal ending of a marriage, and separated couples do not have strong connection to their spouses as married people do, or maybe some of these separated couples are processing divorce. So in this case, doing some entertainments and their kids are the reasons why they are happy.

Part 4: Continent

In this final part, I sort Amazon MTurk workers into six main continents: Asia, Africa, Europe, Northern America, Southern America and Oceania. I want to know wether people’s cultural background will cause differences in terms of happiness.

Compared with other continents, workers from Africa talked about their friends a lot in their happy moments descriptions. And the word job appears only in Africa cluster.

In the Asia cluster, we only see one word that is kind of related to entertainment, that is enjoyed.And many Asian workers mentioned the word birthday which only appears in Asia cluster.

The first 10 popular words of workers from Northern America are somewhat similar to that of Europe. They all contain a couple of words related to entertainments like won, played, watched, and these words rank relatively high. But in terms of people and family, Europe cluster contains word girlfriend followed by the word family, while Northern America cluster contains words home and daughter. Besides, the word dinner shows up in Northern America cluster, it might suggest that dinner is something important in Northern American culture.

Let’s move on to the Southern America cluster. Workers from Southern America talked a lot about shopping and entertainments in their happy moments, because this cluster contains words buy, played and game, and notice that the word buy ranks high.

Finally, let’s check Oceania cluster. The top 10 popular words of happy moments in this cluster is very different from the rest of 5 clusters. Word friend, day and time do not rank very high. And we can see words like read and dog appear in this cluster.

However, as you can see in the y-lab, it reveals that the number of workers from Africa, Southern America and Oceania is quite small, Oceania in particular. So the analysis on popular words in these three clusters cannot give us a typical conclusion.

Conclusions

Happy
  • Generally, people feel happy because they spend positive moments with their friends and families.

  • Events that do not have friends and families involved can also create happiness, such as saved money, walked dog and watched tv etc.

  • Gender, parenthood, marital status and cultural background do vary the factors that make people feel happy.

Reference:

  1. Country Code(ISO 3): Fromhttps://unstats.un.org/unsd/tradekb/knowledgebase/country-code

  2. Countries of The World: From<www.statvision.com/webinars/countries%20of%20the%20world.xls>

  3. Bojack Horseman: Fromhttps://tenor.com/view/awesome-bojack-horseman-gif-9606938

LS0tCnRpdGxlOiAnJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogZGVmYXVsdAogIGh0bWxfZG9jdW1lbnQ6IGRlZmF1bHQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCmBgYHtyLGVjaG89RkFMU0V9CiMgc2V0IHBhdGggZm9yIGRhdGEgZmlsZQpzZXR3ZCgifi9EZXNrdG9wL0dSNTI0MyBBcHBsaWVkIERhdGEgU2NpZW5jZS9Qcm9qZWN0XzEvU3ByaW5nMjAxOS1Qcm9qMS14aW55aWh1dGF5L291dHB1dCIpCmBgYAo+IyoqSGFwcHlEQiA6KSoqCj4jKipXaHkgYXJlIHlvdSBoYXBweT8qKgo+IyoqV2hhdCBtYWtlcyB5b3VyIGhhcHB5IG1vbWVudHMgZGlmZmVyZW50IGZyb20gb3RoZXJzPyoqCjxjZW50ZXI+QnkgWGlueWkgSHU8L2NlbnRlcj4gIAoKPGNlbnRlcj4KIVtCb0phY2sgSG9yc2VtYW5dKC4uL2ZpZ3MvYm9qYWNrLmdpZikgCjwvY2VudGVyPiAgClwKXAo8Zm9udCBzaXplPTM+CkhhcHB5REIgaXMgYSBsYXJnZSBzY2FsZSBjb2xsZWN0aW9uIG9mIGhhcHB5IG1vbWVudHMgb24gQW1hem9uIE1lY2hhbmljYWwgVHVyayAoTVR1cmspIHdvcmtlcnMuIEFuZCBIYXBweURCIGFsc28gY29sbGVjdGVkIHRoZSBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbiBvZiB0aGVzZSB3b3JrZXJzLgoKSGFwcGluZXNzIGlzIHRoZSBlbW90aW9uIHRoYXQgd2UgYWxsIHNoYXJlLiBIb3dldmVyLCB0aGluZ3MgdGhhdCBtYWtlIHVzIGhhcHB5IG1pZ2h0IGJlIHJlbGF0aXZlbHkgZGlmZmVyZW50IGZyb20gZWFjaCBvdGhlci4gVGhlcmVmb3JlLCB0aGlzIHByb2plY3QgYWltcyB0byBhbmFseXplIHdoYXQgbWFrZXMgcGVvcGxlIGhhcHB5LCBhbmQgd2hldGhlciBnZW5kZXIsIG1hcml0YWwgc3RhdHVzLCBwYXJlbnRob29kIGFuZCBjdWx0dXJhbCBiYWNrZ3JvdW5kIHdvdWxkIGRpZmZlciB0aGUgdGhpbmdzIGFuZCBldmVudHMgdGhhdCBtYWtlIHBlb3BsZSBmZWVsIGhhcHB5LgoKYGBge3Igc2V0IHVwLHdhcm5pbmc9RkFMU0UsZXJyb3I9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQpwYWNrYWdlcy51c2VkPWMoInJ2ZXN0IiwgInRpYmJsZSIsICJnZ3B1YnIiLCAiZ2dwbG90MiIsImlncmFwaCIsImdncmFwaCIsIk1hdHJpeCIsCiAgICAgICAgICAgICAgICAic2VudGltZW50ciIsICJncGxvdHMiLCAiZHBseXIiLCJnY29va2Jvb2siLCJ0bSIsICJzeXV6aGV0IiwgCiAgICAgICAgICAgICAgICAiZmFjdG9leHRyYSIsICJzY2FsZXMiLCAiUkNvbG9yQnJld2VyIiwid29yZGNsb3VkIiwiUkFOTiIsCiAgICAgICAgICAgICAgICAicGxvdGx5IiwgInRvcGljbW9kZWxzIiwiYmVlc3dhcm0iLCJjbHVzdGVyIiwidGlkeXRleHQiKSAKCiMgY2hlY2sgcGFja2FnZXMgdGhhdCBuZWVkIHRvIGJlIGluc3RhbGxlZC4KcGFja2FnZXMubmVlZGVkPXNldGRpZmYocGFja2FnZXMudXNlZCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyc2VjdChpbnN0YWxsZWQucGFja2FnZXMoKVssMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFja2FnZXMudXNlZCkpCiMgaW5zdGFsbCBhZGRpdGlvbmFsIHBhY2thZ2VzCmlmKGxlbmd0aChwYWNrYWdlcy5uZWVkZWQpPjApewogIGluc3RhbGwucGFja2FnZXMocGFja2FnZXMubmVlZGVkLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQp9CiMgbG9hZCBsaWJyYXJpZXMKbGlicmFyeSgiTWF0cml4IikKbGlicmFyeSgiZ2dyYXBoIikKbGlicmFyeSgiaWdyYXBoIikKbGlicmFyeSgiZ2dwdWJyIikKbGlicmFyeSgicnZlc3QiKQpsaWJyYXJ5KCJ0aWJibGUiKQpsaWJyYXJ5KCJzZW50aW1lbnRyIikKbGlicmFyeSgiZ3Bsb3RzIikKbGlicmFyeSgiZHBseXIiKQpsaWJyYXJ5KCJzeXV6aGV0IikKbGlicmFyeSgiZmFjdG9leHRyYSIpCmxpYnJhcnkoInNjYWxlcyIpCmxpYnJhcnkoIlJDb2xvckJyZXdlciIpCmxpYnJhcnkoIlJBTk4iKQpsaWJyYXJ5KCJwbG90bHkiKQpsaWJyYXJ5KCJ0b3BpY21vZGVscyIpCmxpYnJhcnkoImJlZXN3YXJtIikKbGlicmFyeSgiY2x1c3RlciIpIApsaWJyYXJ5KCJ3b3JkY2xvdWQiKQpsaWJyYXJ5KCJSQ29sb3JCcmV3ZXIiKQpsaWJyYXJ5KCJnZ3Bsb3QyIikKbGlicmFyeSgiZ2Nvb2tib29rIikKbGlicmFyeSgidG0iKQpsaWJyYXJ5KCJ0aWR5dGV4dCIpCmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoIkRUIikKCnByaW50KFIudmVyc2lvbikKYGBgCgpgYGB7ciBUZXh0IE1pbmluZywgd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CiMjIyBSZWFkIGRhdGEKY2xlYW5faG0gPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3JpdC1wdWJsaWMvSGFwcHlEQi9tYXN0ZXIvaGFwcHlkYi9kYXRhL2NsZWFuZWRfaG0uY3N2JyAgIyBDbGVhbmVkX2htIGZpbGUKZGVtb2dyYXBoaWMgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3JpdC1wdWJsaWMvSGFwcHlEQi9tYXN0ZXIvaGFwcHlkYi9kYXRhL2RlbW9ncmFwaGljLmNzdicgCmNsZWFuLmhtICA9ICByZWFkX2NzdihjbGVhbl9obSkKZGVtb2cgPSAgcmVhZF9jc3YoZGVtb2dyYXBoaWMpCgojIyMgUHJlbGltaW5hcnkgY2xlYW5pbmcgb2YgdGV4dApjb3JwdXMgPSBWQ29ycHVzKFZlY3RvclNvdXJjZShjbGVhbi5obSRjbGVhbmVkX2htKSkKY29ycHVzID0gdG1fbWFwKGNvcnB1cywgc3RyaXBXaGl0ZXNwYWNlKSAgIyByZW1vdmUgd2hpdGUgc3BhY2UKY29ycHVzID0gdG1fbWFwKGNvcnB1cywgY29udGVudF90cmFuc2Zvcm1lcih0b2xvd2VyKSkgIyBjb252ZXJ0IHRvIGxvd2VyIGNhc2UKY29ycHVzID0gdG1fbWFwKGNvcnB1cywgcmVtb3ZlV29yZHMsIHN0b3B3b3JkcygiZW5nbGlzaCIpKSAjIHJlbW92ZSBzdG9wIHdvcmRzCmNvcnB1cyA9IHRtX21hcChjb3JwdXMsIHJlbW92ZVdvcmRzLCBjaGFyYWN0ZXIoMCkpICMgcmVtb3ZlIGVtcHR5IHdvcmRzCmNvcnB1cyA9IHRtX21hcChjb3JwdXMsIHJlbW92ZVB1bmN0dWF0aW9uKSAjIHJlbW92ZSBwdW5jdHVhdGlvbnMKI1ZpZXcoaG0uZGVtb2dyYXBoaWMpCgojIyMgU3RlbSB3b3JkcwpzdGVtbWVkID0gdG1fbWFwKGNvcnB1cywgc3RlbURvY3VtZW50KSAlPiUKICB0aWR5KCkgJT4lCiAgc2VsZWN0KHRleHQpCgpkaWN0ID0gdGlkeShjb3JwdXMpICU+JQogIHNlbGVjdCh0ZXh0KSAlPiUKICB1bm5lc3RfdG9rZW5zKGRpY3Rpb25hcnksIHRleHQpCgpkYXRhKCJzdG9wX3dvcmRzIikKd29yZCA9IGMoImhhcHB5IiwiYWdvIiwieWVzdGVyZGF5IiwibG90IiwidG9kYXkiLCJtb250aHMiLCJtb250aCIsCiAgICAgICAgICAgICAgICAgImhhcHBpZXIiLCJoYXBwaWVzdCIsImxhc3QiLCJ3ZWVrIiwicGFzdCIpCgpzdG9wX3dvcmRzID0gc3RvcF93b3JkcyAlPiUKICBiaW5kX3Jvd3MobXV0YXRlKHRpYmJsZSh3b3JkKSwgbGV4aWNvbiA9ICJ1cGRhdGVkIikpCgpjb21wbGV0ZWQgPSBzdGVtbWVkICU+JQogIG11dGF0ZShpZCA9IHJvd19udW1iZXIoKSkgJT4lCiAgdW5uZXN0X3Rva2VucyhzdGVtcywgdGV4dCkgJT4lICMgc2VwZXJhdGUgc3RlbW1lZCBpbnRvIHNpbmdsZSB3b3JkcywgYW5kIG1hcmsgdGhlaXIgaWQKICBiaW5kX2NvbHMoZGljdCkgJT4lICMgY29sdW1uIGNvbWJpbmUgZGljdCBhbmQgc3RlbW1lZCwgMS10by0xIG1hdGNoaW5nCiAgYW50aV9qb2luKHN0b3Bfd29yZHMsIGJ5ID0gYygiZGljdGlvbmFyeSIgPSAid29yZCIpKSAjIGRlbGV0ZSBtZWFuaW5nbGVzcyB3b3JkcwoKY29tcGxldGVkID0gY29tcGxldGVkICU+JQogIGdyb3VwX2J5KHN0ZW1zKSAlPiUKICBjb3VudChkaWN0aW9uYXJ5KSAlPiUKICBtdXRhdGUod29yZCA9IGRpY3Rpb25hcnlbd2hpY2gubWF4KG4pXSkgJT4lCiAgdW5ncm91cCgpICU+JQogIHNlbGVjdChzdGVtcywgd29yZCkgJT4lCiAgZGlzdGluY3QoKSAlPiUKICByaWdodF9qb2luKGNvbXBsZXRlZCkgJT4lCiAgc2VsZWN0KC1zdGVtcykKCkhhcHB5TW9tZW50cyA9IGNvbXBsZXRlZCAlPiUKICBncm91cF9ieShpZCkgJT4lICAKICBzdW1tYXJpc2UodGV4dCA9IHN0cl9jKHdvcmQsIGNvbGxhcHNlID0gIiAiKSkgJT4lIAogIHVuZ3JvdXAoKSAKCkhhcHB5TW9tZW50cyA9IGNsZWFuLmhtICU+JQogIG11dGF0ZShpZCA9IHJvd19udW1iZXIoKSkgJT4lICAgCiAgaW5uZXJfam9pbihIYXBweU1vbWVudHMpCgojIyMgQ3JlYXRlIDQgY29sdW1ucyBpbiBIYXBweU1vbWVudHMgZm9yIHN0b3JpbmcgZGVtb2dyYXBoaWMgaW5mb3JtYXRpb24KSGFwcHlNb21lbnRzJGNvdW50cnkgPSByZXAoInRiYSIsIGxlbmd0aChIYXBweU1vbWVudHMkd2lkKSkKSGFwcHlNb21lbnRzJGdlbmRlciA9IHJlcCgidGJhIiwgbGVuZ3RoKEhhcHB5TW9tZW50cyR3aWQpKQpIYXBweU1vbWVudHMkbWFyaXRhbCA9IHJlcCgidGJhIiwgbGVuZ3RoKEhhcHB5TW9tZW50cyR3aWQpKQpIYXBweU1vbWVudHMkcGFyZW50aG9vZCA9IHJlcCgidGJhIiwgbGVuZ3RoKEhhcHB5TW9tZW50cyR3aWQpKQoKIyMjIG1hdGNoaW5nIHRoZSBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbiB3aXRoIHRoZSBjb3JyZWN0IHdvcmtlcnMgdGhyb3VnaCB0aGVpciB3aWQKZm9yIChpIGluIHNvcnQodW5pcXVlKEhhcHB5TW9tZW50cyR3aWQpKSkgewogIAogIGluZGV4ID0gd2hpY2goSGFwcHlNb21lbnRzJHdpZCA9PSBpKQogIEhhcHB5TW9tZW50c1tpbmRleCwiY291bnRyeSJdID0gZGVtb2ckY291bnRyeVt3aGljaChkZW1vZyR3aWQgPT0gaSldCiAgSGFwcHlNb21lbnRzW2luZGV4LCJnZW5kZXIiXSA9IGRlbW9nJGdlbmRlclt3aGljaChkZW1vZyR3aWQgPT0gaSldCiAgSGFwcHlNb21lbnRzW2luZGV4LCJtYXJpdGFsIl0gPSBkZW1vZyRtYXJpdGFsW3doaWNoKGRlbW9nJHdpZCA9PSBpKV0KICBIYXBweU1vbWVudHNbaW5kZXgsInBhcmVudGhvb2QiXSA9IGRlbW9nJHBhcmVudGhvb2Rbd2hpY2goZGVtb2ckd2lkID09IGkpXQoKfQoKaG0uZGVtb2dyYXBoaWMgPSBIYXBweU1vbWVudHNbLC1jKDEsMyw0LDYsNyw4LDEwKV0KIyB3cml0ZV9jc3YoaG0uZGVtb2dyYXBoaWMsICJ+L0Rlc2t0b3AvR1I1MjQzIEFwcGxpZWQgRGF0YSBTY2llbmNlL1Byb2plY3RfMS9TcHJpbmcyMDE5LVByb2oxLXhpbnlpaHV0YXkvb3V0cHV0L2htLmRlbW9ncmFwaGljLmNzdiIpCiMgd3JpdGVfY3N2KEhhcHB5TW9tZW50cywgIn4vRGVza3RvcC9HUjUyNDMgQXBwbGllZCBEYXRhIFNjaWVuY2UvUHJvamVjdF8xL1NwcmluZzIwMTktUHJvajEteGlueWlodXRheS9vdXRwdXQvSGFwcHlNb21lbnQuY3N2IikKCmBgYAoKIyBTZWN0aW9uIDE6IE92ZXJ2aWV3IG9mIFRoZSBIYXBweSBNb21lbnRzCgpUaGlzIHNlY3Rpb24gZm9jdXNlcyBvbiBhbmFseXppbmcgYWxsIGhhcHB5IG1vbWVudHMgcmVnYXJkbGVzcyBvZiB3b3JrZXJzJyBkZW1vZ3JhcGhpYyBpbmZvcm1hdGlvbi4KCiMjIFBhcnQgMTogV29yZGNsb3VkCgpXb3JkcyB0aGF0IGZyZXF1ZW50bHkgYXBwZWFyZWQgaW4gTVR1cmsgd29ya2VycycgaGFwcHkgbW9tZW50cyBkZXNjcmlwdGlvbnMgYXJlOiAqKmZyaWVuZCoqLCAqKmRheSoqLCAqKnRpbWUqKiwgKip3YXRjaGVkKiosICoqZmFtaWx5KiogYW5kICoqaG9tZSoqIGV0Yy4gVGh1cywgZ2VuZXJhbGx5IHBlb3BsZSB3aWxsIGZlZWwgaGFwcHkgYWJvdXQgdGhpbmdzIG9yIGV2ZW50cyByZWxhdGVkIHRvIHRoZWlyIGZyaWVuZHMsIGZhbWlsaWVzLCB3YXRjaGluZyBzaG93cyBhbmQgc28gb24uCgpgYGB7ciB3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KY2xlYW4uY29ycHVzID0gVkNvcnB1cyhWZWN0b3JTb3VyY2UoaG0uZGVtb2dyYXBoaWMkdGV4dCkpCnRkbS5hbGwgPSBUZXJtRG9jdW1lbnRNYXRyaXgoY2xlYW4uY29ycHVzKQp0ZG0udGlkeSA9IHRpZHkodGRtLmFsbCkKdGRtLm92ZXJhbGwgPSBzdW1tYXJpc2UoZ3JvdXBfYnkodGRtLnRpZHksIHRlcm0pLCBzdW0oY291bnQpKQoKd29yZGNsb3VkKHRkbS5vdmVyYWxsJHRlcm0sIHRkbS5vdmVyYWxsJGBzdW0oY291bnQpYCwKICAgICAgICAgIHNjYWxlID0gYyg1LDAuMSksCiAgICAgICAgICBtYXgud29yZHMgPSAzNTAsCiAgICAgICAgICBtaW4uZnJlcSA9IDUsCiAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwKICAgICAgICAgIHJvdC5wZXIgPSAwLjMsCiAgICAgICAgICB1c2Uuci5sYXlvdXQgPSBULAogICAgICAgICAgcmFuZG9tLmNvbG9yID0gRkFMU0UsCiAgICAgICAgICBjb2xvcnMgPSBicmV3ZXIucGFsKDgsIkFjY2VudCIpKQpgYGAKCgoKCiMjIFBhcnQgMjogUmVsYXRpb25zaGlwcyBCZXR3ZWVuIFdvcmRzCgpJbiB0aGlzIHBhcnQsIEkgYW0gaW50ZXJlc3RlZCBpbiB0aGUgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHdvcmRzIGluIGFsbCB0aGUgaGFwcHkgbW9tZW50cyBkZXNjcmlwdGlvbnMuIEkgd2FudCB0byB3aGV0aGVyIGV4YW1pbmUgd2hpY2ggd29yZHMgdGVuZCB0byBmb2xsb3cgb3RoZXJzIGltbWVkaWF0ZWx5LCBvciB0aGF0IHRlbmQgdG8gY28tb2NjdXIgd2l0aGluIHRoZSBzYW1lIGRvY3VtZW50cy4KCgpgYGB7ciB3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KaG0udGV4dCA9IGRhdGFfZnJhbWUobGluZSA9IDE6ZGltKEhhcHB5TW9tZW50cylbMV0sIHRleHQgPSBIYXBweU1vbWVudHMkdGV4dCkKCmhtX2JpZ3JhbXMgPSBobS50ZXh0ICU+JQogIHVubmVzdF90b2tlbnMoYmlncmFtLCB0ZXh0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuID0gMikgCgpiaWdyYW1zX3NlcGFyYXRlZCA9IGhtX2JpZ3JhbXMgJT4lCiAgc2VwYXJhdGUoYmlncmFtLCBjKCJ3b3JkMSIsICJ3b3JkMiIpLCBzZXAgPSAiICIpCgpiaWdyYW1zX2ZpbHRlcmVkID0gYmlncmFtc19zZXBhcmF0ZWQgJT4lCiAgZmlsdGVyKCF3b3JkMSAlaW4lIHN0b3Bfd29yZHMkd29yZCkgJT4lCiAgZmlsdGVyKCF3b3JkMiAlaW4lIHN0b3Bfd29yZHMkd29yZCkKCiMgbmV3IGJpZ3JhbSBjb3VudHM6CmJpZ3JhbV9jb3VudHMgPSBiaWdyYW1zX2ZpbHRlcmVkICU+JSAKICBjb3VudCh3b3JkMSwgd29yZDIsIHNvcnQgPSBUUlVFKQoKYmlncmFtX2dyYXBoID0gYmlncmFtX2NvdW50cyAlPiUKICBmaWx0ZXIobiA+IDE1MCkgJT4lICAjIGZpbHRlciBmb3Igb25seSByZWxhdGl2ZWx5IGNvbW1vbiBjb21iaW5hdGlvbnMKICBncmFwaF9mcm9tX2RhdGFfZnJhbWUoKQoKc2V0LnNlZWQoMjAxOSkKCmEgPSBncmlkOjphcnJvdyh0eXBlID0gImNsb3NlZCIsIGxlbmd0aCA9IHVuaXQoLjEsICJpbmNoZXMiKSkKCmdncmFwaChiaWdyYW1fZ3JhcGgsIGxheW91dCA9ICJmciIpICsKICBnZW9tX2VkZ2VfbGluayhhZXMoZWRnZV9hbHBoYSA9IG4pLCBzaG93LmxlZ2VuZCA9IEZBTFNFLAogICAgICAgICAgICAgICAgIGFycm93ID0gYSwgZW5kX2NhcCA9IGNpcmNsZSguMDUsICdpbmNoZXMnKSkgKwogIGdlb21fbm9kZV9wb2ludChjb2xvciA9ICJwaW5rIiwgc2l6ZSA9IDMpICsKICBnZW9tX25vZGVfdGV4dChhZXMobGFiZWwgPSBuYW1lKSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpICsKICB0aGVtZV92b2lkKCkKYGBgCgpJIHZpc3VhbGl6ZSBzb21lIGRldGFpbHMgb2YgdGhlIHRleHQgc3RydWN0dXJlLiBXZSBjYW4gc2VlIHRoYXQgd29yZHMgbGlrZSAqKnZpc2l0KiosICoqcGFydHkqKiBhbmQgKipzY2hvb2wqKiBhcmUgb2Z0ZW4gZm9sbG93ZWQgYnkgdGhlIHdvcmQgKipmcmllbmQqKiwgd2hpY2ggbWVhbnMgd2hlbiB0aGVzZSBldmVudHMgYXJlIHJlbGF0ZWQgdG8gZnJpZW5kcywgcGVvcGxlIHVzdWFsbHkgZ2V0IGhhcHB5LiAKCldlIGFsc28gc2VlIHNvbWUgcGFpcnMgb3IgdHJpcGxldHMgYWxvbmcgdGhlIG91dHNpZGUgdGhhdCBmb3JtIGNvbW1vbiBzaG9ydCBwaHJhc2VzIHJlbGF0ZWQgdG8gaGFwcHkgbW9tZW50cywgc3VjaCBhcyAqKmJyb3VnaHQgaG9tZSoqIGFuZCAqKnJlYWQgYm9vayoqLgoKCiMjIFBhcnQgMzogVG9waWMgTW9kZWxpbmcKCk5vdyBpbiB0aGlzIHBhcnQsIEkgYXBwbHkgdG9waWMgbW9kZWxpbmcgdG8gYWxsIGhhcHB5IG1vbWVudHMgY29ycHVzLiBJIHNldCB0aGUgbnVtYmVyIG9mIHRvcGljcyB0byBiZSA5LCB3aGljaCBpcyB0aGUgc2FtZSBhcyB0aGUgbnVtYmVyIG9mICd0b3BpY19kaWN0JyBpbiBIYXBweURCIGRhdGEgZm9sZGVyLgoKYGBge3Igd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmNvbWJfaG0gPSB2ZWN0b3IobW9kZSA9ICJjaGFyYWN0ZXIiLGxlbmd0aCA9IGxlbmd0aCh1bmlxdWUoSGFwcHlNb21lbnRzJHdpZCkpKQoKZm9yIChpIGluIHNvcnQodW5pcXVlKEhhcHB5TW9tZW50cyR3aWQpKSkgewogIGluZGV4ID0gd2hpY2goSGFwcHlNb21lbnRzJHdpZCA9PSBpKQogIGNvbWJfaG1baV0gPSBwYXN0ZShIYXBweU1vbWVudHMkdGV4dFtpbmRleF0sIGNvbGxhcHNlID0gIiAiKQp9CgpobS5jb3JwdXMgPSBWQ29ycHVzKFZlY3RvclNvdXJjZShjb21iX2htKSkKZHRtLmFsbCA9IERvY3VtZW50VGVybU1hdHJpeChobS5jb3JwdXMpCnJvd1RvdGFscyA9IGFwcGx5KGR0bS5hbGwsIDEsIHN1bSkgCmR0bSAgPSBkdG0uYWxsW3Jvd1RvdGFscz4gMCwgXQoKaG1fbGRhID0gTERBKGR0bSwgayA9IDksIGNvbnRyb2wgPSBsaXN0KHNlZWQgPSAxMjM0KSkKaG1fdG9waWNzID0gdGlkeShobV9sZGEsIG1hdHJpeCA9ICJiZXRhIikKCmhtX3RvcF90ZXJtcyA9IGhtX3RvcGljcyAlPiUKICBncm91cF9ieSh0b3BpYykgJT4lCiAgdG9wX24oMTAsIGJldGEpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBhcnJhbmdlKHRvcGljLCAtYmV0YSkKCmhtX3RvcF90ZXJtcyAlPiUKICBtdXRhdGUodGVybSA9IHJlb3JkZXIodGVybSwgYmV0YSkpICU+JQogIGdncGxvdChhZXModGVybSwgYmV0YSwgZmlsbCA9IGZhY3Rvcih0b3BpYykpKSArCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGKSArCiAgZmFjZXRfd3JhcCh+IHRvcGljLCBzY2FsZXMgPSAiZnJlZSIpICsKICBjb29yZF9mbGlwKCkKYGBgCgoKQWNjb3JkaW5nIHRvIHRoZSBhYm92ZSBwbG90cyBhbmQgdGhlIHdvcmRzIHJlbGF0aW9uc2hpcHMgd2UganVzdCBmb3VuZCBvdXQsIEkgc29ydCB0aGUgdG9waWNzIGFzIGZvbGxvd3M6CgokJApUb3BpY1wgMTogU2hvcHBpbmcgXFwKVG9waWNcIDI6IEVudGVydGFpbm1lbnQgXFwKVG9waWNcIDM6IFBlb3BsZSBcXApUb3BpY1wgNDogUGV0cyBcXApUb3BpY1wgNTogV29yayBcXApUb3BpY1wgNjogRXhlcmNpc2VcXApUb3BpY1wgNzogRm9vZCBcXApUb3BpY1wgODogU2Nob29sIFxcClRvcGljXCA5OiBGYW1pbHkKJCQKCiMgU2VjdGlvbiAyOiBBbmFseXplIEhhcHB5IE1vbWVudHMgaW4gRGlmZmVyZW50IENsdXN0ZXJzCgpJbiB0aGlzIHNlY3Rpb24sIEkgZ3JvdXAgSGFwcHlEQiBkYXRhIGludG8gc2ltaWxhciBjYXRlZ29yaWVzIGFjY29yZGluZyB0byBBbWF6b24gTVR1cmsgd29ya2VycycgZGVtb2dyYXBoaWMgZGF0YSBpbmNsdWRpbmcgZ2VuZGVyLCBwYXJlbnRob29kLCBtYXJpdGFsIHN0YXR1cyBhbmQgY29udGluZW50LgoKIyMgUGFydCAxOiBHZW5kZXIKCmBgYHtyIFdvcmRDbG91ZCwgd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9Cm1hbGUuaG0gPSBmaWx0ZXIoaG0uZGVtb2dyYXBoaWMsZ2VuZGVyID09ICJtIikkdGV4dAp0ZG0ubWFsZSA9IFRlcm1Eb2N1bWVudE1hdHJpeChWQ29ycHVzKFZlY3RvclNvdXJjZShtYWxlLmhtKSkpCnRkbS50aWR5Lm1hbGUgPSB0aWR5KHRkbS5tYWxlKQp0ZG1fbWFsZSA9IHN1bW1hcmlzZShncm91cF9ieSh0ZG0udGlkeS5tYWxlLCB0ZXJtKSwgc3VtKGNvdW50KSkKCmZlbWFsZS5obSA9IGZpbHRlcihobS5kZW1vZ3JhcGhpYyxnZW5kZXIgPT0gImYiKSR0ZXh0CnRkbS5mZW1hbGUgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2UoZmVtYWxlLmhtKSkpCnRkbS50aWR5LmZlbWFsZSA9IHRpZHkodGRtLmZlbWFsZSkKdGRtX2ZlbWFsZSA9IHN1bW1hcmlzZShncm91cF9ieSh0ZG0udGlkeS5mZW1hbGUsIHRlcm0pLCBzdW0oY291bnQpKQpgYGAKCioqTWFsZSoqCmBgYHtyIG1hbGUsd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CndvcmRjbG91ZCh0ZG1fZmVtYWxlJHRlcm0sIHRkbV9mZW1hbGUkYHN1bShjb3VudClgLAogICAgICAgICAgc2NhbGUgPSBjKDUsMC4xKSwKICAgICAgICAgIG1heC53b3JkcyA9IDEwMCwKICAgICAgICAgIG1pbi5mcmVxID0gMSwKICAgICAgICAgIHJhbmRvbS5vcmRlciA9IEZBTFNFLAogICAgICAgICAgcm90LnBlciA9IDAuMywKICAgICAgICAgIHVzZS5yLmxheW91dCA9IFQsCiAgICAgICAgICByYW5kb20uY29sb3IgPSBGQUxTRSwKICAgICAgICAgIGNvbG9ycyA9IGJyZXdlci5wYWwoOCwiQWNjZW50IikpCmBgYAoKKipGZW1hbGUqKgoKYGBge3IgZmVtYWxlLHdhcm5pbmc9RkFMU0UsZXJyb3I9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQp3b3JkY2xvdWQodGRtX21hbGUkdGVybSwgdGRtX21hbGUkYHN1bShjb3VudClgLAogICAgICAgICAgc2NhbGUgPSBjKDUsMC4xKSwKICAgICAgICAgIG1heC53b3JkcyA9IDEwMCwKICAgICAgICAgIG1pbi5mcmVxID0gMSwKICAgICAgICAgIHJhbmRvbS5vcmRlciA9IEZBTFNFLAogICAgICAgICAgcm90LnBlciA9IDAuMywKICAgICAgICAgIHVzZS5yLmxheW91dCA9IFQsCiAgICAgICAgICByYW5kb20uY29sb3IgPSBGQUxTRSwKICAgICAgICAgIGNvbG9ycyA9IGJyZXdlci5wYWwoOCwiQWNjZW50IikpCgpgYGAKClRoZSB3b3JkY2xvdWRzIGxvb2sgZ29vZCwgYnV0IGV4Y2VwdCBmb3Igd29yZHMgKipkYXkqKiwgKip0aW1lKiogYW5kICoqZnJpZW5kKiosIHdlIGNhbiBoYXJkbHkgc2VlIG90aGVyIHdvcmRzIGNsZWFybHkuIFNvIGxldCdzIGNoZWNrIHRoZXNlIHBvcHVsYXIgd29yZHMgYnkgb3RoZXIgdmlzdWFsaXphdGlvbiBwbG90LgoKYGBge3IgIEdlbmRlciBmcmVxIGdncGxvdCx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KbWFsZS53b3JkcyA9IGRhdGFfZnJhbWUobGluZSA9IDE6bGVuZ3RoKG1hbGUuaG0pLCB0ZXh0ID0gbWFsZS5obSkKbWFsZV93b3JkcyA9IG1hbGUud29yZHMgJT4lCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0KSAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lCiAgZmlsdGVyKG4gPiAyMjY2KSAlPiUKICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpIAoKZmVtYWxlLndvcmRzID0gZGF0YV9mcmFtZShsaW5lID0gMTpsZW5ndGgoZmVtYWxlLmhtKSwgdGV4dCA9IGZlbWFsZS5obSkKZmVtYWxlX3dvcmRzID0gZmVtYWxlLndvcmRzICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMTcyNSkgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAKCnAxID0gZ2dwbG90KGRhdGEgPSBtYWxlX3dvcmRzLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBuKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAicHVycGxlIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJNYWxlIFRvcCAxMCBLZXkgV29yZHMiLCAKICAgICAgICAgICAgICAgIHggPSAiSGFwcHkgTW9tZW50cyIsIHkgPSAiRnJlcXVlbmN5IikKCgpwMiA9IGdncGxvdChkYXRhID0gZmVtYWxlX3dvcmRzLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBuKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAicmVkIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJGZW1hbGUgVG9wIDEwIEtleSBXb3JkcyIsCiAgICAgICAgICAgICAgICB4ID0gIkhhcHB5IE1vbWVudHMiLCB5ID0gIkZyZXF1ZW5jeSIpCiAgICAgICAgCnJlcXVpcmUoImdyaWRFeHRyYSIpCmdyaWQuYXJyYW5nZShhcnJhbmdlR3JvYihwMSwgcDIpKQpgYGAKCkluIGJvdGggcGxvdHMsIHRoZSBmaXJzdCAzIHdvcmRzIGFyZSAqKmRheSoqLCAqKnRpbWUqKiBhbmQgKipmcmllbmQqKi4gQW5kIFRoZWlyIGZyZXF1ZW5jaWVzIGFyZSBhbG1vc3QgZXF1aXZhbGVudCBpbiBmZW1hbGUgZGF0YSBzZXQsIHdoaWxlIGluIG1hbGUgZGF0YSBzZXQsIHRoZSB3b3JkIGZyZXF1ZW5jeSBvZiAqKmZyaWVuZCoqIGlzIG11Y2ggaGlnaGVyIHRoYW4gdGhlIG90aGVyIHR3byB3b3Jkcy4gVGhlIGZvdXJ0aCB3b3JkIGluIGJvdGggZGF0YSBzZXQgaXMgc3BvdXNlLCB3aGljaCBpcyBnb29kLiAKCkluIHRoZSBtYWxlIGRhdGEgc2V0LCB3b3JkcyAqKnBsYXllZCoqIGFuZCAqKndhdGNoZWQqKiByYW5rIGhpZ2hlciB0aGFuICoqZmFtaWx5KiouIEJ1dCBpbiBmZW1hbGUgZGF0YSBzZXQsIHdvcmRzIHJlbGF0ZWQgdG8gZmFtaWx5IGFuZCBob21lIGFyZSBpbiB0aGUgZnJvbnQuIFNvIHlvdSBjYW4gc2VlIHRoZSBkaWZmZXJlbmNlcyBvZiBoYXBweSBtb21lbnRzIGJldHdlZW4gZmVtYWxlIGFuZCBtYWxlLgoKIyMgUGFydCAyOiBQYXJlbnRob29kCgpgYGB7ciBQYXJlbnRob29kIFdvcmRDbG91ZCx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KeWVzLmhtID0gZmlsdGVyKGhtLmRlbW9ncmFwaGljLHBhcmVudGhvb2QgPT0gInkiKSR0ZXh0CnRkbS55ZXMgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2UoeWVzLmhtKSkpCnRkbS50aWR5LnllcyA9IHRpZHkodGRtLnllcykKdGRtX3llcyA9IHN1bW1hcmlzZShncm91cF9ieSh0ZG0udGlkeS55ZXMsIHRlcm0pLCBzdW0oY291bnQpKQoKbm8uaG0gPSBmaWx0ZXIoaG0uZGVtb2dyYXBoaWMscGFyZW50aG9vZCA9PSAibiIpJHRleHQKdGRtLm5vID0gVGVybURvY3VtZW50TWF0cml4KFZDb3JwdXMoVmVjdG9yU291cmNlKG5vLmhtKSkpCnRkbS50aWR5Lm5vID0gdGlkeSh0ZG0ubm8pCnRkbV9ubyA9IHN1bW1hcmlzZShncm91cF9ieSh0ZG0udGlkeS5ubywgdGVybSksIHN1bShjb3VudCkpCmBgYAoKYGBge3IgeWVzLCB3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0Kd29yZGNsb3VkKHRkbV95ZXMkdGVybSwgdGRtX3llcyRgc3VtKGNvdW50KWAsCiAgICAgICAgICBzY2FsZSA9IGMoNSwwLjEpLAogICAgICAgICAgbWF4LndvcmRzID0gMTAwLAogICAgICAgICAgbWluLmZyZXEgPSAxLAogICAgICAgICAgcmFuZG9tLm9yZGVyID0gRkFMU0UsCiAgICAgICAgICByb3QucGVyID0gMC4zLAogICAgICAgICAgdXNlLnIubGF5b3V0ID0gVCwKICAgICAgICAgIHJhbmRvbS5jb2xvciA9IEZBTFNFLAogICAgICAgICAgY29sb3JzID0gYnJld2VyLnBhbCg4LCJBY2NlbnQiKSkKYGBgCgpgYGB7ciBubyx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KCndvcmRjbG91ZCh0ZG1fbm8kdGVybSwgdGRtX25vJGBzdW0oY291bnQpYCwKICAgICAgICAgIHNjYWxlID0gYyg1LDAuMSksCiAgICAgICAgICBtYXgud29yZHMgPSAxMDAsCiAgICAgICAgICBtaW4uZnJlcSA9IDEsCiAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwKICAgICAgICAgIHJvdC5wZXIgPSAwLjMsCiAgICAgICAgICB1c2Uuci5sYXlvdXQgPSBULAogICAgICAgICAgcmFuZG9tLmNvbG9yID0gRkFMU0UsCiAgICAgICAgICBjb2xvcnMgPSBicmV3ZXIucGFsKDgsIkFjY2VudCIpKQoKYGBgCgpUaGUgcG9wdWxhciB3b3JkcyBpbiB0aGVzZSB0d28gY2x1c3RlcnMgYXJlIGFwcGFyZW50bHkgZGlmZmVyZW50LiBGb3IgdGhvc2Ugd2hvIGhhdmUga2lkcywgYWx0aG91Z2ggKipkYXkqKiwgKip0aW1lKiogYW5kICoqZnJpZW5kcyoqIGFyZSBzdGlsbCB0aGUgZnJlcXVlbnQgd29yZHMgaW4gdGhlaXIgaGFwcHkgbW9tZW50cyBkZXNjcmlwdGlvbnMsIGZhbWlseSByZWxhdGVkIHdvcmRzIGxpa2UgKipkYXVnaHRlcioqIGFuZCAqKnNvbioqIGNvbnRyaWJ1dGUgdG8gdGhlaXIgaGFwcHkgbW9tZW50cyBhIGxvdC4gCgpXaGlsZSBpbiB0aGUgbm8tY2hpbGQgY2x1c3RlciwgZXhjZXB0IGZvciB3b3JkcyAqKmRheSoqLCAqKnRpbWUqKiBhbmQgKipmcmllbmRzKiosIHdlIGNhbiBzZWUgd29yZHMgcmVsYXRlZCB0byBlbnRlcnRhaW5tZW50IHNob3cgdXAgZnJlcXVlbnRseSwgc3VjaCBhcyAqKmdhbWUqKiwgKipwbGF5ZWQqKiBhbmQgKip3YXRjaGVkKiouIEFuZCB0aGlzIHJlc3VsdCBpcyBxdWl0ZSByZWFzb25hYmxlLgoKYGBge3IgIFBhcmVudGhvb2QgZ2dwbG90LHdhcm5pbmc9RkFMU0UsZXJyb3I9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQp5ZXNfd29yZHMgPSBkYXRhX2ZyYW1lKGxpbmUgPSAxOmxlbmd0aCh5ZXMuaG0pLCB0ZXh0ID0geWVzLmhtKQp5ZXNfd29yZHMgPSB5ZXNfd29yZHMgJT4lCiAgdW5uZXN0X3Rva2Vucyh3b3JkLCB0ZXh0KSAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgJT4lCiAgZmlsdGVyKG4gPiAxNzQ5KSAlPiUKICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpIAoKbm9fd29yZHMgPSBkYXRhX2ZyYW1lKGxpbmUgPSAxOmxlbmd0aChuby5obSksIHRleHQgPSBuby5obSkKbm9fd29yZHMgPSBub193b3JkcyAlPiUKICB1bm5lc3RfdG9rZW5zKHdvcmQsIHRleHQpICU+JQogIGNvdW50KHdvcmQsIHNvcnQgPSBUUlVFKSAlPiUKICBmaWx0ZXIobiA+IDIyMjYpICU+JQogIG11dGF0ZSh3b3JkID0gcmVvcmRlcih3b3JkLCBuKSkgCgpwMyA9IGdncGxvdChkYXRhID0geWVzX3dvcmRzLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBuKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAib3JhbmdlIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJQYXJlbnRob29kIFRvcCAxMCBLZXkgV29yZHMiLCAKICAgICAgICAgICAgICAgIHggPSAiSGFwcHkgTW9tZW50cyIsIHkgPSAiRnJlcXVlbmN5IikKCnA0ID0gZ2dwbG90KGRhdGEgPSBub193b3JkcyxhZXMoeCA9IHJlb3JkZXIod29yZCwtbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gbikpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImxpZ2h0Ymx1ZSIpKwogICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKwogICAgICAgICAgIGxhYnModGl0bGUgPSAiQ2hpbGRsZXNzbmVzcyBUb3AgMTAgS2V5IFdvcmRzIiwgCiAgICAgICAgICAgICAgICB4ID0gIkhhcHB5IE1vbWVudHMiLCB5ID0gIkZyZXF1ZW5jeSIpCiAgICAgICAgCmdyaWQuYXJyYW5nZShhcnJhbmdlR3JvYihwMywgcDQpKQpgYGAKCiMjIFBhcnQgMzogTWFyaXRhbCBTdGF0dXMKCmBgYHtyIE1hcml0YWwgZ2dwbG90cyx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KbWFycmllZC5obSA9IGZpbHRlcihobS5kZW1vZ3JhcGhpYyxtYXJpdGFsID09ICJtYXJyaWVkIikkdGV4dAp0ZG0ubWFycmllZCA9IFRlcm1Eb2N1bWVudE1hdHJpeChWQ29ycHVzKFZlY3RvclNvdXJjZShtYXJyaWVkLmhtKSkpCm0ubWFycmllZCA9IGFzLm1hdHJpeCh0ZG0ubWFycmllZCkKdi5tYXJyaWVkID0gc29ydChyb3dTdW1zKG0ubWFycmllZCksZGVjcmVhc2luZz1UUlVFKQpkLm1hcnJpZWQgPSBkYXRhLmZyYW1lKHdvcmQgPSBuYW1lcyh2Lm1hcnJpZWQpLGZyZXE9di5tYXJyaWVkKQoKc2luZ2xlLmhtID0gZmlsdGVyKGhtLmRlbW9ncmFwaGljLG1hcml0YWwgPT0gInNpbmdsZSIpJHRleHQKc2luZ2xlX3dvcmRzID0gZGF0YV9mcmFtZShsaW5lID0gMTpsZW5ndGgoc2luZ2xlLmhtKSwgdGV4dCA9IHNpbmdsZS5obSkKc2luZ2xlX3dvcmRzID0gc2luZ2xlX3dvcmRzICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpICU+JQogIGZpbHRlcihuID4gMTk4MikgJT4lCiAgbXV0YXRlKHdvcmQgPSByZW9yZGVyKHdvcmQsIG4pKSAKCmRpdm9yY2VkLmhtID0gZmlsdGVyKGhtLmRlbW9ncmFwaGljLG1hcml0YWwgPT0gImRpdm9yY2VkIikkdGV4dAp0ZG0uZGl2b3JjZWQgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2UoZGl2b3JjZWQuaG0pKSkKbS5kaXZvcmNlZCA9IGFzLm1hdHJpeCh0ZG0uZGl2b3JjZWQpCnYuZGl2b3JjZWQgPSBzb3J0KHJvd1N1bXMobS5kaXZvcmNlZCksZGVjcmVhc2luZz1UUlVFKQpkLmRpdm9yY2VkID0gZGF0YS5mcmFtZSh3b3JkID0gbmFtZXModi5kaXZvcmNlZCksZnJlcT12LmRpdm9yY2VkKQoKc2VwYXJhdGVkLmhtID0gZmlsdGVyKGhtLmRlbW9ncmFwaGljLG1hcml0YWwgPT0gInNlcGFyYXRlZCIpJHRleHQKdGRtLnNlcGFyYXRlZCA9IFRlcm1Eb2N1bWVudE1hdHJpeChWQ29ycHVzKFZlY3RvclNvdXJjZShzZXBhcmF0ZWQuaG0pKSkKbS5zZXBhcmF0ZWQgPSBhcy5tYXRyaXgodGRtLnNlcGFyYXRlZCkKdi5zZXBhcmF0ZWQgPSBzb3J0KHJvd1N1bXMobS5zZXBhcmF0ZWQpLGRlY3JlYXNpbmc9VFJVRSkKZC5zZXBhcmF0ZWQgPSBkYXRhLmZyYW1lKHdvcmQgPSBuYW1lcyh2LnNlcGFyYXRlZCksZnJlcT12LnNlcGFyYXRlZCkKCndpZG93ZWQuaG0gPSBmaWx0ZXIoaG0uZGVtb2dyYXBoaWMsbWFyaXRhbCA9PSAid2lkb3dlZCIpJHRleHQKdGRtLndpZG93ZWQgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2Uod2lkb3dlZC5obSkpKQptLndpZG93ZWQgPSBhcy5tYXRyaXgodGRtLndpZG93ZWQpCnYud2lkb3dlZCA9IHNvcnQocm93U3VtcyhtLndpZG93ZWQpLGRlY3JlYXNpbmc9VFJVRSkKZC53aWRvd2VkID0gZGF0YS5mcmFtZSh3b3JkID0gbmFtZXModi53aWRvd2VkKSxmcmVxPXYud2lkb3dlZCkKCnA1ID0gZ2dwbG90KGRhdGEgPSBkLm1hcnJpZWRbMToxMCxdLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBmcmVxKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAicGluayIpKwogICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKwogICAgICAgICAgIGxhYnModGl0bGUgPSAiTWFycmllZCIsIHggPSAiSGFwcHkgTW9tZW50cyIsCiAgICAgICAgICAgICAgICB5ID0gIkZyZXF1ZW5jeSIpCgpwNiA9IGdncGxvdChkYXRhID0gc2luZ2xlX3dvcmRzLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBuKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAibGlnaHRibHVlIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJTaW5nbGUiLCB4ID0gIkhhcHB5IE1vbWVudHMiLCAKICAgICAgICAgICAgICAgIHkgPSAiRnJlcXVlbmN5IikKCnA3ID0gZ2dwbG90KGRhdGEgPSBkLmRpdm9yY2VkWzE6MTAsXSxhZXMoeCA9IHJlb3JkZXIod29yZCwtZnJlcSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZnJlcSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImdyZXkiKSsKICAgICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICAgICAgICAgICBsYWJzKHRpdGxlID0gIkRpdm9yY2VkIiwgeCA9ICJIYXBweSBNb21lbnRzIiwgCiAgICAgICAgICAgICAgICB5ID0gIkZyZXF1ZW5jeSIpCgpwOCA9IGdncGxvdChkYXRhID0gZC5zZXBhcmF0ZWRbMToxMCxdLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBmcmVxKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiZGFya2dyZWVuIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJTZXBhcmF0ZWQiLCB4ID0gIkhhcHB5IE1vbWVudHMiLCAKICAgICAgICAgICAgICAgIHkgPSAiRnJlcXVlbmN5IikKCnA5ID0gZ2dwbG90KGRhdGEgPSBkLndpZG93ZWRbMToxMCxdLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBmcmVxKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAiYmxhY2siKSsKICAgICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICAgICAgICAgICBsYWJzKHRpdGxlID0gIldpZG93ZWQiLCB4ID0gIkhhcHB5IE1vbWVudHMiLCAKICAgICAgICAgICAgICAgIHkgPSAiRnJlcXVlbmN5IikKZ2dhcnJhbmdlKHA1LCBwNiwgcDcsIHA4LCBwOSwgbnJvdyA9IDIsIG5jb2wgPSAzKQpgYGAKCkluIGVhY2ggbWFyaXRhbCBzdGF0dXMsIHdvcmRzICoqZGF5KiosICoqdGltZSoqIGFuZCAqKmZyaWVuZHMqKiBhcmUgc3RpbGwgZnJlcXVlbnRseSBhcHBlYXIuIEFuZCBpbiBjbHVzdGVyIHNpbmdsZSwgd29yZHMgcmVsYXRlZCB0byBlbnRlcnRhaW5tZW50IGFyZSBwb3B1bGFyLiBJbiBjbHVzdGVyIG1hcnJpZWQsIGZhbWlseSByZWxhdGVkIHdvcmRzIHJhbmsgaGlnaGVyIHRoYW4gdGhlIHdvcmRzICoqd2F0Y2hlZCoqLCB3aGljaCBzdWdnZXN0cyB0aGF0IHBvc2l0aXZlIHRoaW5ncyBvciBldmVudHMgcmVsYXRlZCB0byBmYW1pbHkgdXN1YWxseSBtYWtlIG1hcnJpZWQgcGVvcGxlIGhhcHB5IGFuZCB0aGVzZSBoYXBweSBtb21lbnRzIHRlbmQgdG8gYmUgcmVtZW1iZXJlZC4KCkluIGNsdXN0ZXJzIGRpdm9yY2VkIGFuZCBzZXBhcmF0ZWQsIHdvcmRzICoqZGF1Z2h0ZXIqKiwgKipzb24qKiBhbmQgKip3YXRjaGVkKiogcmFuayBoaWdoLCB3aGlsZSB3b3JkcyBob21lIHJhbmtzIGxvd2VyLiBUbyBteSBtaW5kLCB0aGlzIG1ha2VzIHNlbnNlIHNpbmNlIGRpdm9yY2UgaXMgYSBmb3JtYWwgZW5kaW5nIG9mIGEgbWFycmlhZ2UsIGFuZCBzZXBhcmF0ZWQgY291cGxlcyBkbyBub3QgaGF2ZSBzdHJvbmcgY29ubmVjdGlvbiB0byB0aGVpciBzcG91c2VzIGFzIG1hcnJpZWQgcGVvcGxlIGRvLCBvciBtYXliZSBzb21lIG9mIHRoZXNlIHNlcGFyYXRlZCBjb3VwbGVzIGFyZSBwcm9jZXNzaW5nIGRpdm9yY2UuIFNvIGluIHRoaXMgY2FzZSwgZG9pbmcgc29tZSBlbnRlcnRhaW5tZW50cyBhbmQgdGhlaXIga2lkcyBhcmUgdGhlIHJlYXNvbnMgd2h5IHRoZXkgYXJlIGhhcHB5LgoKCiMjIFBhcnQgNDogQ29udGluZW50CgpJbiB0aGlzIGZpbmFsIHBhcnQsIEkgc29ydCBBbWF6b24gTVR1cmsgd29ya2VycyBpbnRvIHNpeCBtYWluIGNvbnRpbmVudHM6IEFzaWEsIEFmcmljYSwgRXVyb3BlLCBOb3J0aGVybiBBbWVyaWNhLCBTb3V0aGVybiBBbWVyaWNhIGFuZCBPY2VhbmlhLiBJIHdhbnQgdG8ga25vdyB3ZXRoZXIgcGVvcGxlJ3MgY3VsdHVyYWwgYmFja2dyb3VuZCB3aWxsIGNhdXNlIGRpZmZlcmVuY2VzIGluIHRlcm1zIG9mIGhhcHBpbmVzcy4KXApgYGB7ciBDb3VudHJpZXMgUHJlLXByb2Nlc3Npbmcsd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9Cm5hdGlvbi5hYmJyZSA9IHJlYWQuY3N2KCJjb3VudHJ5IGFiYnJldmlhdGlvbi5jc3YiLCBoZWFkZXIgPSBUKQoKbmEgPSB3aGljaChpcy5uYShobS5kZW1vZ3JhcGhpYyRjb3VudHJ5KSkgIApobS5jb3VudHJ5ID0gaG0uZGVtb2dyYXBoaWNbLW5hLF0KCm1hcmsgPSBjKCkKZm9yIChpIGluIDE6bGVuZ3RoKGhtLmNvdW50cnkkY291bnRyeSkpewogICAgbWFya1tpXSA9IGdyZXAocGF0dGVybiA9IGhtLmNvdW50cnkkY291bnRyeVtpXSwgbmF0aW9uLmFiYnJlJEFiYnJldmF0aW9uKQp9CgpobS5jb3VudHJ5JFJlZ2lvbiA9IGFzLmNoYXJhY3RlcihuYXRpb24uYWJicmUkUmVnaW9uW21hcmtdKQoKcmVnaW9uID0gVkNvcnB1cyhWZWN0b3JTb3VyY2UoaG0uY291bnRyeSRSZWdpb24pKQpyZWdpb24gPSB0bV9tYXAocmVnaW9uLCBzdHJpcFdoaXRlc3BhY2UpICAjIHJlbW92ZSB3aGl0ZSBzcGFjZQpyZWcgPSB0aWR5KHJlZ2lvbikKaG0uY291bnRyeSRSZWdpb24gPSByZWckdGV4dAoKQUYgPSB3aGljaChobS5jb3VudHJ5JFJlZ2lvbiA9PSAiTk9SVEhFUk4gQUZSSUNBICIgfCBobS5jb3VudHJ5JFJlZ2lvbiA9PSAiU1VCLVNBSEFSQU4gQUZSSUNBICIpCgpBUyA9IHdoaWNoKGhtLmNvdW50cnkkUmVnaW9uID09ICJBU0lBIChFWC4gTkVBUiBFQVNUKSAiIHwgaG0uY291bnRyeSRSZWdpb24gPT0gIk5FQVIgRUFTVCAiIHwgaG0uY291bnRyeSRjb3VudHJ5ID09ICJBUk0iIHwgaG0uY291bnRyeSRjb3VudHJ5ID09ICJLQVoiKQoKRVUgPSAgd2hpY2goaG0uY291bnRyeSRSZWdpb24gPT0gIldFU1RFUk4gRVVST1BFICIgIHwgaG0uY291bnRyeSRSZWdpb24gPT0gIkVBU1RFUk4gRVVST1BFICIgfCBobS5jb3VudHJ5JFJlZ2lvbiA9PSAiQkFMVElDUyAiIHwgaG0uY291bnRyeSRjb3VudHJ5ID09ICJNREEiIHwgaG0uY291bnRyeSRjb3VudHJ5ID09ICJVS1IiIHwgaG0uY291bnRyeSRjb3VudHJ5ID09ICJSVVMiKQoKTi5BID0gd2hpY2goaG0uY291bnRyeSRSZWdpb24gPT0gIk5PUlRIRVJOIEFNRVJJQ0EgIikKClMuQSA9IHdoaWNoKGhtLmNvdW50cnkkUmVnaW9uID09ICJMQVRJTiBBTUVSLiAmIENBUklCICIgKQoKT0MgPSB3aGljaChobS5jb3VudHJ5JFJlZ2lvbiA9PSAiT0NFQU5JQSAiKQpgYGAKCmBgYHtyIFNvcnQgY29udGluZW50cyx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KQUYuaG0gPSBobS5jb3VudHJ5JHRleHRbQUZdCnRkbS5BRiA9IFRlcm1Eb2N1bWVudE1hdHJpeChWQ29ycHVzKFZlY3RvclNvdXJjZShBRi5obSkpKQptLkFGID0gYXMubWF0cml4KHRkbS5BRikKdi5BRiA9IHNvcnQocm93U3VtcyhtLkFGKSxkZWNyZWFzaW5nPVRSVUUpCmQuQUYgPSBkYXRhLmZyYW1lKHdvcmQgPSBuYW1lcyh2LkFGKVsxOjEwXSxmcmVxPXJvdW5kKDEwMCp2LkFGWzE6MTBdL3N1bSh2LkFGKSwyKSkKCkFTLmhtID0gaG0uY291bnRyeSR0ZXh0W0FTXQp0ZG0uQVMgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2UoQVMuaG0pKSkKbS5BUyA9IGFzLm1hdHJpeCh0ZG0uQVMpCnYuQVMgPSBzb3J0KHJvd1N1bXMobS5BUyksZGVjcmVhc2luZz1UUlVFKQpkLkFTID0gZGF0YS5mcmFtZSh3b3JkID0gbmFtZXModi5BUylbMToxMF0sZnJlcT1yb3VuZCgxMDAqdi5BU1sxOjEwXS9zdW0odi5BUyksMikpCgpFVS5obSA9IGhtLmNvdW50cnkkdGV4dFtFVV0KdGRtLkVVID0gVGVybURvY3VtZW50TWF0cml4KFZDb3JwdXMoVmVjdG9yU291cmNlKEVVLmhtKSkpCm0uRVUgPSBhcy5tYXRyaXgodGRtLkVVKQp2LkVVID0gc29ydChyb3dTdW1zKG0uRVUpLGRlY3JlYXNpbmc9VFJVRSkKZC5FVSA9IGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHYuRVUpWzE6MTBdLGZyZXE9cm91bmQoMTAwKnYuRVVbMToxMF0vc3VtKHYuRVUpLDIpKQoKTkEuaG0gPSBobS5jb3VudHJ5JHRleHRbTi5BXQpOQV93b3JkcyA9IGRhdGFfZnJhbWUobGluZSA9IDE6bGVuZ3RoKE5BLmhtKSwgdGV4dCA9IE5BLmhtKQpOQV93b3JkcyA9IE5BX3dvcmRzICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgdGV4dCkgJT4lCiAgY291bnQod29yZCwgc29ydCA9IFRSVUUpIAoKdG90YWwgPSBzdW0oTkFfd29yZHMkbikgIyB0b3RhbCBzdW0gb2Ygd29yZHMgaW4gTkFfd29yZHMKCk5BX3dvcmRzID0gTkFfd29yZHMgJT4lCiAgZmlsdGVyKG4gPiAyOTcyKSAlPiUKICBtdXRhdGUod29yZCA9IHJlb3JkZXIod29yZCwgbikpIAoKY291bnQgPSBhcy5udW1lcmljKE5BX3dvcmRzJG4pCmQuTkEgPSBkYXRhLmZyYW1lKHdvcmQgPSBhcy5jaGFyYWN0ZXIoTkFfd29yZHMkd29yZCksIGZyZXE9cm91bmQoMTAwKmNvdW50L3RvdGFsLDIpKQoKU0EuaG0gPSBobS5jb3VudHJ5JHRleHRbUy5BXQp0ZG0uU0EgPSBUZXJtRG9jdW1lbnRNYXRyaXgoVkNvcnB1cyhWZWN0b3JTb3VyY2UoU0EuaG0pKSkKbS5TQSA9IGFzLm1hdHJpeCh0ZG0uU0EpCnYuU0EgPSBzb3J0KHJvd1N1bXMobS5TQSksZGVjcmVhc2luZz1UUlVFKQpkLlNBID0gZGF0YS5mcmFtZSh3b3JkID0gbmFtZXModi5TQSlbMToxMF0sZnJlcT1yb3VuZCgxMDAqdi5TQVsxOjEwXS9zdW0odi5TQSksMikpCgpPQy5obSA9IGhtLmNvdW50cnkkdGV4dFtPQ10KdGRtLk9DID0gVGVybURvY3VtZW50TWF0cml4KFZDb3JwdXMoVmVjdG9yU291cmNlKE9DLmhtKSkpCm0uT0MgPSBhcy5tYXRyaXgodGRtLk9DKQp2Lk9DID0gc29ydChyb3dTdW1zKG0uT0MpLGRlY3JlYXNpbmc9VFJVRSkKZC5PQyA9IGRhdGEuZnJhbWUod29yZCA9IG5hbWVzKHYuT0MpWzE6MTBdLGZyZXE9cm91bmQoMTAwKnYuT0NbMToxMF0vc3VtKHYuT0MpLDIpKQoKaG0ucmVnaW9uID0gZGF0YS5mcmFtZShBRiA9IGQuQUYkd29yZCwgCiAgICAgICAgICAgICAgICAgICAgICAgQVMgPSBkLkFTJHdvcmQsIAogICAgICAgICAgICAgICAgICAgICAgIEVVID0gZC5FVSR3b3JkLCAKICAgICAgICAgICAgICAgICAgICAgICBOLkEgPSBkLk5BJHdvcmQsIAogICAgICAgICAgICAgICAgICAgICAgIFNBID0gZC5TQSR3b3JkLCAKICAgICAgICAgICAgICAgICAgICAgICBPQyA9IGQuT0Mkd29yZCkKCmhtLnJlZy5mcmVxID0gZGF0YS5mcmFtZShBRi5mcmVxID0gZC5BRiRmcmVxLAogICAgICAgICAgICAgICAgICAgICAgICAgQVMuZnJlcSA9IGQuQVMkZnJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgIEVVLmZyZXEgPSBkLkVVJGZyZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICBOQS5mcmVxID0gZC5OQSRmcmVxLAogICAgICAgICAgICAgICAgICAgICAgICAgU0EuZnJlcSA9IGQuU0EkZnJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgIE9DLmZyZXEgPSBkLk9DJGZyZXEpCmBgYAoKYGBge3IgV29ybGRNYXAsd2FybmluZz1GQUxTRSxlcnJvcj1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CmFmLm5hdGlvbiA9IHVuaXF1ZShobS5jb3VudHJ5JGNvdW50cnlbQUZdKQphcy5uYXRpb24gPSB1bmlxdWUoaG0uY291bnRyeSRjb3VudHJ5W0FTXSkKZXUubmF0aW9uID0gdW5pcXVlKGhtLmNvdW50cnkkY291bnRyeVtFVV0pCm5hLm5hdGlvbiA9IHVuaXF1ZShobS5jb3VudHJ5JGNvdW50cnlbTi5BXSkKc2EubmF0aW9uID0gdW5pcXVlKGhtLmNvdW50cnkkY291bnRyeVtTLkFdKQpvYy5uYXRpb24gPSB1bmlxdWUoaG0uY291bnRyeSRjb3VudHJ5W09DXSkKCmNvbnRpbmVudCA9IGMoIkFmcmljYSIsICJBc2lhIiwgIkV1cm9wZSIsICJOb3J0aGVybiBBbWVyaWNhIiwgIlNvdXRoZXJuIEFtZXJpY2EiLCAiT2NlYW5pYSIpCgpQb3AgPSBjKGxlbmd0aChBRiksbGVuZ3RoKEFTKSxsZW5ndGgoRVUpLGxlbmd0aChOLkEpLGxlbmd0aChTLkEpLGxlbmd0aChPQykpCgpuYXRpb24uaW4uY29udGluZW50ID1jKGxlbmd0aChhZi5uYXRpb24pLGxlbmd0aChhcy5uYXRpb24pLGxlbmd0aChldS5uYXRpb24pLGxlbmd0aChuYS5uYXRpb24pLGxlbmd0aChzYS5uYXRpb24pLGxlbmd0aChvYy5uYXRpb24pKQoKCmhvdmVyID0gY2hhcmFjdGVyKDYpCgpmb3IoaSBpbiAxOjYpewogIGhvdmVyW2ldID0gcGFzdGUoICc8Yj4nLCBjb250aW5lbnRbaV0sJzo8YnI+JywgCiAgICAgICAgICAgICAgICAgICAgcGFzdGUoJyAgICcsJzwvYj4nLGhtLnJlZ2lvbltbaV1dLCAnOiAnLCBobS5yZWcuZnJlcVtbaV1dLCclIDxicj4nLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbGxhcHNlPSIiKSwKICAgICAgICAgICAgICAgICAgICBjb2xsYXBzZT0iIikKfQoKcG9wID0gcmVwKFBvcCxuYXRpb24uaW4uY29udGluZW50KQpjb250ID0gcmVwKGNvbnRpbmVudCxuYXRpb24uaW4uY29udGluZW50KQphbGwubmF0aW9uID0gYyhhZi5uYXRpb24sYXMubmF0aW9uLGV1Lm5hdGlvbixuYS5uYXRpb24sc2EubmF0aW9uLG9jLm5hdGlvbikKcmFuay50ZXh0ID0gcmVwKGhvdmVyLG5hdGlvbi5pbi5jb250aW5lbnQpCmRhdGFmb3JtYXAgPSBkYXRhLmZyYW1lKE5hdGlvbiA9IGFsbC5uYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgIFdvcmtlciA9IHBvcCwKICAgICAgICAgICAgICAgICAgICAgICAgQ29udGluZW50ID0gY29udCwKICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHJhbmsudGV4dCkKCmwgPSBsaXN0KGNvbG9yID0gdG9SR0IoImRhcmtncmV5IiksIHdpZHRoID0gMC41KQoKZyA9IGxpc3QoCiAgc2hvd2ZyYW1lID0gRkFMU0UsCiAgc2hvd2NvYXN0bGluZXMgPSBGQUxTRSwKICBwcm9qZWN0aW9uID0gbGlzdCh0eXBlID0gJ01lcmNhdG9yJykKKQoKcCA9IHBsb3RfZ2VvKGRhdGFmb3JtYXApICU+JQogIGFkZF90cmFjZSgKICAgIHogPSB+V29ya2VyLCBjb2xvciA9IH5Xb3JrZXIsIGNvbG9ycyA9ICdCbHVlcycsCiAgICB0ZXh0ID0gfnRleHQsIGxvY2F0aW9ucyA9IH5OYXRpb24sIG1hcmtlciA9IGxpc3QobGluZSA9IGwpCiAgKSAlPiUKICBjb2xvcmJhcih0aXRsZSA9ICdOdW1iZXIgb2YgQW1hem9uIE1UdXJrIFdvcmtlcnMnKSAlPiUKICBsYXlvdXQoCiAgICB0aXRsZSA9ICdUb3AgMTAga2V5IHdvcmRzIG9mIEhhcHB5IE1vbWVudHMgaW4gRWFjaCBDb250aW5lbnQnLAogICAgZ2VvID0gZywKICAgIGF1dG9zaXplID0gRkFMU0UsCiAgICB3aWR0aCA9IDkwMCwKICAgIG1hcmdpbiA9IGxpc3QodD0yMCwgbD0wLCByPTAsIGQ9MCkKICApCgpwCmBgYAoKQ29tcGFyZWQgd2l0aCBvdGhlciBjb250aW5lbnRzLCB3b3JrZXJzIGZyb20gQWZyaWNhIHRhbGtlZCBhYm91dCB0aGVpciBmcmllbmRzIGEgbG90IGluIHRoZWlyIGhhcHB5IG1vbWVudHMgZGVzY3JpcHRpb25zLiBBbmQgdGhlIHdvcmQgKipqb2IqKiBhcHBlYXJzIG9ubHkgaW4gQWZyaWNhIGNsdXN0ZXIuCgpJbiB0aGUgQXNpYSBjbHVzdGVyLCB3ZSBvbmx5IHNlZSBvbmUgd29yZCB0aGF0IGlzIGtpbmQgb2YgcmVsYXRlZCB0byBlbnRlcnRhaW5tZW50LCB0aGF0IGlzICoqZW5qb3llZCoqLkFuZCBtYW55IEFzaWFuIHdvcmtlcnMgbWVudGlvbmVkIHRoZSB3b3JkICoqYmlydGhkYXkqKiB3aGljaCBvbmx5IGFwcGVhcnMgaW4gQXNpYSBjbHVzdGVyLiAgCgpUaGUgZmlyc3QgMTAgcG9wdWxhciB3b3JkcyBvZiB3b3JrZXJzIGZyb20gTm9ydGhlcm4gQW1lcmljYSBhcmUgc29tZXdoYXQgc2ltaWxhciB0byB0aGF0IG9mIEV1cm9wZS4gVGhleSBhbGwgY29udGFpbiBhIGNvdXBsZSBvZiB3b3JkcyByZWxhdGVkIHRvIGVudGVydGFpbm1lbnRzIGxpa2UgKip3b24qKiwgKipwbGF5ZWQqKiwgKip3YXRjaGVkKiosIGFuZCB0aGVzZSB3b3JkcyByYW5rIHJlbGF0aXZlbHkgaGlnaC4gQnV0IGluIHRlcm1zIG9mIHBlb3BsZSBhbmQgZmFtaWx5LCBFdXJvcGUgY2x1c3RlciBjb250YWlucyB3b3JkICoqZ2lybGZyaWVuZCoqIGZvbGxvd2VkIGJ5IHRoZSB3b3JkIGZhbWlseSwgd2hpbGUgTm9ydGhlcm4gQW1lcmljYSBjbHVzdGVyIGNvbnRhaW5zIHdvcmRzICoqaG9tZSoqIGFuZCAqKmRhdWdodGVyKiouIEJlc2lkZXMsIHRoZSB3b3JkICoqZGlubmVyKiogc2hvd3MgdXAgaW4gTm9ydGhlcm4gQW1lcmljYSBjbHVzdGVyLCBpdCBtaWdodCBzdWdnZXN0IHRoYXQgZGlubmVyIGlzIHNvbWV0aGluZyBpbXBvcnRhbnQgaW4gTm9ydGhlcm4gQW1lcmljYW4gY3VsdHVyZS4KCkxldCdzIG1vdmUgb24gdG8gdGhlIFNvdXRoZXJuIEFtZXJpY2EgY2x1c3Rlci4gV29ya2VycyBmcm9tIFNvdXRoZXJuIEFtZXJpY2EgdGFsa2VkIGEgbG90IGFib3V0IHNob3BwaW5nIGFuZCBlbnRlcnRhaW5tZW50cyBpbiB0aGVpciBoYXBweSBtb21lbnRzLCBiZWNhdXNlIHRoaXMgY2x1c3RlciBjb250YWlucyB3b3JkcyAqKmJ1eSoqLCAqKnBsYXllZCoqIGFuZCAqKmdhbWUqKiwgYW5kIG5vdGljZSB0aGF0IHRoZSB3b3JkICoqYnV5KiogcmFua3MgaGlnaC4KCkZpbmFsbHksIGxldCdzIGNoZWNrIE9jZWFuaWEgY2x1c3Rlci4gVGhlIHRvcCAxMCBwb3B1bGFyIHdvcmRzIG9mIGhhcHB5IG1vbWVudHMgaW4gdGhpcyBjbHVzdGVyIGlzIHZlcnkgZGlmZmVyZW50IGZyb20gdGhlIHJlc3Qgb2YgNSBjbHVzdGVycy4gV29yZCAqKmZyaWVuZCoqLCAqKmRheSoqIGFuZCAqKnRpbWUqKiBkbyBub3QgcmFuayB2ZXJ5IGhpZ2guIEFuZCB3ZSBjYW4gc2VlIHdvcmRzIGxpa2UgKipyZWFkKiogYW5kICoqZG9nKiogYXBwZWFyIGluIHRoaXMgY2x1c3Rlci4gCmBgYHtyIGdncGxvdCx3YXJuaW5nPUZBTFNFLGVycm9yPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KcC5hZiA9IGdncGxvdChkYXRhID0gZC5BRixhZXMoeCA9IHJlb3JkZXIod29yZCwtZnJlcSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZnJlcSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInBpbmsiKSsKICAgICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICAgICAgICAgICBsYWJzKHRpdGxlID0gIkFmcmljYSIsIHggPSAiSGFwcHkgTW9tZW50cyIsCiAgICAgICAgICAgICAgICB5ID0gIkZyZXF1ZW5jeSIpCgpwLmFzID0gIGdncGxvdChkYXRhID0gZC5BUyxhZXMoeCA9IHJlb3JkZXIod29yZCwtZnJlcSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZnJlcSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gIm9yYW5nZSIpKwogICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKwogICAgICAgICAgIGxhYnModGl0bGUgPSAiQXNpYSIsIHggPSAiSGFwcHkgTW9tZW50cyIsCiAgICAgICAgICAgICAgICB5ID0gIkZyZXF1ZW5jeSIpCiAgCnAuZXUgPSAgZ2dwbG90KGRhdGEgPSBkLkVVLGFlcyh4ID0gcmVvcmRlcih3b3JkLC1mcmVxKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSBmcmVxKSkrCiAgICAgICAgICAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIGZpbGwgPSAicmVkIikrCiAgICAgICAgICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkrCiAgICAgICAgICAgbGFicyh0aXRsZSA9ICJFdXJvcGUiLCB4ID0gIkhhcHB5IE1vbWVudHMiLAogICAgICAgICAgICAgICAgeSA9ICJGcmVxdWVuY3kiKQogIApwLm5hID0gZ2dwbG90KGRhdGEgPSBOQV93b3JkcyxhZXMoeCA9IHJlb3JkZXIod29yZCwtbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gbikpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInB1cnBsZSIpKwogICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpKwogICAgICAgICAgIGxhYnModGl0bGUgPSAiTm9ydGhlcm4gQW1lcmljYSIsIHggPSAiSGFwcHkgTW9tZW50cyIsIAogICAgICAgICAgICAgICAgeSA9ICJGcmVxdWVuY3kiKQpwLnNhID0gIGdncGxvdChkYXRhID0gZC5TQSxhZXMoeCA9IHJlb3JkZXIod29yZCwtZnJlcSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ID0gZnJlcSkpKwogICAgICAgICAgIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gImJsdWUiKSsKICAgICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICAgICAgICAgICBsYWJzKHRpdGxlID0gIlNvdXRoZXJuIEFtZXJpY2EiLCB4ID0gIkhhcHB5IE1vbWVudHMiLAogICAgICAgICAgICAgICAgeSA9ICJGcmVxdWVuY3kiKQoKcC5vYyA9ICBnZ3Bsb3QoZGF0YSA9IGQuT0MsYWVzKHggPSByZW9yZGVyKHdvcmQsLWZyZXEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IGZyZXEpKSsKICAgICAgICAgICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJsaWdodGJsdWUiKSsKICAgICAgICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICAgICAgICAgICBsYWJzKHRpdGxlID0gIk9jZWFuaWEiLCB4ID0gIkhhcHB5IE1vbWVudHMiLAogICAgICAgICAgICAgICAgeSA9ICJGcmVxdWVuY3kiKQpnZ2FycmFuZ2UocC5hZiwgcC5hcywgcC5ldSwgcC5uYSwgcC5zYSwgcC5vYywgbmNvbCA9IDMsIG5yb3cgPSAyKQpgYGAKCkhvd2V2ZXIsIGFzIHlvdSBjYW4gc2VlIGluIHRoZSB5LWxhYiwgaXQgcmV2ZWFscyB0aGF0IHRoZSBudW1iZXIgb2Ygd29ya2VycyBmcm9tIEFmcmljYSwgU291dGhlcm4gQW1lcmljYSBhbmQgT2NlYW5pYSBpcyBxdWl0ZSBzbWFsbCwgT2NlYW5pYSBpbiBwYXJ0aWN1bGFyLiBTbyB0aGUgYW5hbHlzaXMgb24gcG9wdWxhciB3b3JkcyBpbiB0aGVzZSB0aHJlZSBjbHVzdGVycyBjYW5ub3QgZ2l2ZSB1cyBhIHR5cGljYWwgY29uY2x1c2lvbi4KCj4gIyMgQ29uY2x1c2lvbnMKPGNlbnRlcj4KIVtIYXBweV0oLi4vZmlncy9oYXBweS5naWYpIAo8L2NlbnRlcj4gIAoKCgoqIEdlbmVyYWxseSwgcGVvcGxlIGZlZWwgaGFwcHkgYmVjYXVzZSB0aGV5IHNwZW5kIHBvc2l0aXZlIG1vbWVudHMgd2l0aCB0aGVpciBmcmllbmRzIGFuZCBmYW1pbGllcy4gCgoqIEV2ZW50cyB0aGF0IGRvIG5vdCBoYXZlIGZyaWVuZHMgYW5kIGZhbWlsaWVzIGludm9sdmVkIGNhbiBhbHNvIGNyZWF0ZSBoYXBwaW5lc3MsIHN1Y2ggYXMgc2F2ZWQgbW9uZXksIHdhbGtlZCBkb2cgYW5kIHdhdGNoZWQgdHYgZXRjLgoKKiBHZW5kZXIsIHBhcmVudGhvb2QsIG1hcml0YWwgc3RhdHVzIGFuZCBjdWx0dXJhbCBiYWNrZ3JvdW5kIGRvIHZhcnkgdGhlIGZhY3RvcnMgdGhhdCBtYWtlIHBlb3BsZSBmZWVsIGhhcHB5LgoKCjxmb250IHNpemU9MS41PgoqKlJlZmVyZW5jZToqKiAgIAoKMS4gQ291bnRyeSBDb2RlKElTTyAzKTogRnJvbTxodHRwczovL3Vuc3RhdHMudW4ub3JnL3Vuc2QvdHJhZGVrYi9rbm93bGVkZ2ViYXNlL2NvdW50cnktY29kZT4gICAKCjIuIENvdW50cmllcyBvZiBUaGUgV29ybGQ6IEZyb208d3d3LnN0YXR2aXNpb24uY29tL3dlYmluYXJzL2NvdW50cmllcyUyMG9mJTIwdGhlJTIwd29ybGQueGxzPiAgCgozLiBCb2phY2sgSG9yc2VtYW46IEZyb208aHR0cHM6Ly90ZW5vci5jb20vdmlldy9hd2Vzb21lLWJvamFjay1ob3JzZW1hbi1naWYtOTYwNjkzOD4gPC9mcm9udD4KCgoKCgo=